home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 February: Tool Chest / Apple Developer CD Series Tool Chest February 1996 (Apple Computer)(1996).iso / Sample Code / AppsToGo / Kibitz / Print.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-09-22  |  8.5 KB  |  316 lines  |  [TEXT/MPS ]

  1. /*
  2. ** Apple Macintosh Developer Technical Support
  3. **
  4. ** MultiFinder-Aware Shell Application
  5. **
  6. ** File:        print.c
  7. ** Written by:  Eric Soldan
  8. ** Based on:    Code from Pete "Luke" Alexander.
  9. **
  10. ** Copyright © 1989-1992 Apple Computer, Inc.
  11. ** All rights reserved. */
  12.  
  13.  
  14.  
  15. /*****************************************************************************/
  16.  
  17.  
  18.  
  19. #include "Kibitz.h"                /* Get the Kibitz includes/typedefs, etc.    */
  20. #include "KibitzCommon.h"        /* Get the stuff in common with rez.        */
  21. #include "Kibitz.protos"        /* Get the prototypes for Kibitz.            */
  22.  
  23. #ifndef __ERRORS__
  24. #include <Errors.h>
  25. #endif
  26.  
  27. #ifndef __RESOURCES__
  28. #include <Resources.h>
  29. #endif
  30.  
  31.  
  32.  
  33. /*****************************************************************************/
  34.  
  35.  
  36.  
  37. pascal void            PrintIdleProc(void);
  38. short                gPrintPage;
  39. static DialogPtr    PrintingStatusDialog;
  40.  
  41.  
  42.  
  43. /*****************************************************************************/
  44. /*****************************************************************************/
  45.  
  46. #ifdef applec
  47. #pragma segment Print
  48. #endif
  49.  
  50. /*****************************************************************************/
  51. /*****************************************************************************/
  52.  
  53.  
  54.  
  55. /* This print-loop function is designed to be called under various situations.
  56. ** The big issue that it handles is finder printing.  If multiple documents
  57. ** are to be printed from the finder, the user should only see one job dialog
  58. ** for all the files.  (If a job dialog is shown for each file, how does the
  59. ** user know for which file the dialog is for?)  So, for situations where
  60. ** there is more than one file to be printed, call this code the first time
  61. ** with the firstJob boolean true.  Normally, the jobDlg boolean will also
  62. ** be true, except that under 7.0, you may be printing in the background.
  63. ** If this is the case, you don't want a job dialog for even the first file,
  64. ** and you should pass in false for the jobDlg boolean in this case.  For
  65. ** files 2-N, you should pass false for both booleans.  For regular application
  66. ** printing, you should pass true for both booleans, since the file is the
  67. ** first (only) file, and you are not in the background.
  68. **
  69. ** After calling this function to print a document, you need to call it
  70. ** again with a nil document handle.  The print record for the first (or only)
  71. ** document printed is preserved in a static variable.  This is so that the
  72. ** job dialog information can be passed on to documents 2-N in the print job.
  73. ** Calling this function with the document handle nil tells this function
  74. ** that you are done printing documents, and that the print record for the
  75. ** first job can be disposed of. */
  76.  
  77. OSErr    AppPrintDocument(FileRecHndl frHndl, Boolean jobDlg, Boolean firstJob)
  78. {
  79.     OSErr            err;
  80.     THPrint            prRecHndl;
  81.     TPPrPort        printPort;
  82.     GrafPtr            oldPort;
  83.     short            i, keepResFile, copies, fstPage, lstPage;
  84.     TPrStatus        status;
  85.     ControlHandle    proceedButton;
  86.     Rect             rct;
  87.     PrIdleUPP        pidleupp;
  88.  
  89.     static THPrint    prMergeHndl;
  90.  
  91.     if (!frHndl) {
  92.         if (prMergeHndl) {
  93.             DisposeHandle((Handle)prMergeHndl);
  94.             prMergeHndl = nil;
  95.         }
  96.         return(noErr);
  97.     }
  98.  
  99.     PrintingStatusDialog = nil;
  100.  
  101.     if (!(prRecHndl = (THPrint)NewHandle(sizeof(TPrint)))) return(memFullErr);
  102.         /* If we can't generate a print record handle, we are out of here. */
  103.  
  104.     BlockMove((Ptr)&((*frHndl)->doc.print), (Ptr)(*prRecHndl), sizeof(TPrint));
  105.         /* Get the document's print info into the print record handle. */
  106.  
  107.     GetPort(&oldPort);
  108.  
  109.     DoSetCursor(&qd.arrow);
  110.     PrOpen();
  111.     err = PrError();
  112.  
  113.     if (!err) {
  114.         keepResFile = CurResFile();
  115.  
  116.         if (!(*frHndl)->doc.printRecValid) {
  117.             PrintDefault(prRecHndl);            /* The document print record was never 
  118.             err = PrError();                    ** initialized.  Now is is. */
  119.         }            
  120.         if (!err) {
  121.             PrValidate(prRecHndl);        /* Do this just 'cause Apple says so. */
  122.             err = PrError();
  123.         }
  124.         if (!err) {
  125.             if (jobDlg) {                /* User gets to click some buttons. */
  126.                 if (!(PrJobDialog(prRecHndl))) err = userCanceledErr;
  127.                 else                           err = PrError();
  128.             }
  129.         }
  130.         if (!err) {
  131.             if (!firstJob) {
  132.                 fstPage = (*prMergeHndl)->prJob.iFstPage;
  133.                 lstPage = (*prMergeHndl)->prJob.iLstPage;
  134.                 PrJobMerge(prMergeHndl, prRecHndl);
  135.                 (*prMergeHndl)->prJob.iFstPage = (*prRecHndl)->prJob.iFstPage = fstPage;
  136.                 (*prMergeHndl)->prJob.iLstPage = (*prRecHndl)->prJob.iLstPage = lstPage;
  137.                 err = PrError();
  138.             }
  139.         }
  140.  
  141.         if (!err) {            /* Put the defaulted/validated/jobDlg'ed print record in the doc. */
  142.             pidleupp = nil;
  143.             fstPage = (*prRecHndl)->prJob.iFstPage;
  144.             lstPage = (*prRecHndl)->prJob.iLstPage;
  145.             copies  = (*prRecHndl)->prJob.iCopies;
  146.             BlockMove((Ptr)(*prRecHndl), (Ptr)&((*frHndl)->doc.print), sizeof(TPrint));
  147.             (*frHndl)->doc.printRecValid = true;
  148.  
  149.             ParamText((*frHndl)->fileState.fss.name, nil, nil, nil);
  150.             PrintingStatusDialog = GetNewDialog(rPrStatusDlg, nil, (WindowPtr)-1);
  151.             if (PrintingStatusDialog) {
  152.                 GetDialogItem(PrintingStatusDialog, 1, &i, (Handle *)&proceedButton, &rct);
  153.                 HiliteControl(proceedButton, 255);
  154.                     /* Setup the proceed/pause/cancel dialog with the document name. */
  155.                 pidleupp = NewPrIdleProc(PrintIdleProc);
  156.                 (*prRecHndl)->prJob.pIdleProc = pidleupp;
  157.                 UseResFile(keepResFile);
  158.                     /* Hook in the proceed/pause/cancel dialog. */
  159.             }
  160.  
  161.             for (i = 1; (i <= copies) && (!err); ++i) {
  162.  
  163.                 printPort = PrOpenDoc(prRecHndl, nil, nil);
  164.                 if (!(err = PrError())) {
  165.  
  166.                     gPrintPage = 1;
  167.                     while (gPrintPage <= lstPage) {
  168.  
  169.                         PrOpenPage(printPort, nil);
  170.  
  171.                         if (!(err = PrError()))
  172.                             ImageDocument(frHndl, false);
  173.                                 /* Do the print thing here. */
  174.  
  175.                         PrClosePage(printPort);
  176.  
  177.                         if (!gPrintPage) break;
  178.                         ++gPrintPage;
  179.                     }
  180.                     gPrintPage = 0;
  181.                     PrCloseDoc(printPort);
  182.                 }
  183.             }
  184.             if (pidleupp) DisposeRoutineDescriptor(pidleupp);
  185.         }
  186.  
  187.         if (
  188.             (!err) &&
  189.             ((*prRecHndl)->prJob.bJDocLoop == bSpoolLoop) &&
  190.             (!(err = PrError()))
  191.         ) {
  192.             PrPicFile(prRecHndl, nil, nil, nil, &status);
  193.             err = PrError();
  194.         }
  195.     }
  196.  
  197.     if (firstJob) prMergeHndl = prRecHndl;
  198.     else          DisposeHandle((Handle)prRecHndl);
  199.  
  200.     if (PrintingStatusDialog) DisposeDialog(PrintingStatusDialog);
  201.  
  202.     PrClose();
  203.     SetPort(oldPort);
  204.  
  205.     return(err);
  206. }
  207.  
  208.  
  209.  
  210. /*****************************************************************************/
  211.  
  212.  
  213.  
  214. /* PrintIdleProc will handle events in the 'Printing Status Dialog' which
  215. ** gives the user the option to 'Proceed', 'Pause', or 'Cancel' the current
  216. ** printing job during print time.
  217. **
  218. ** The buttons:
  219. **        1: Proceed
  220. **        2: Pause
  221. **        3: Cancel  */
  222.  
  223. pascal void        PrintIdleProc(void)
  224. {
  225.     Boolean                button, paused;
  226.     ControlHandle        pauseButton, proceedButton;
  227.     DialogPtr            aDialog;
  228.     EventRecord            anEvent;
  229.     GrafPtr                oldPort;
  230.     Rect                 rct;
  231.     short                item, itemType, keepResFile;
  232.  
  233.     GetPort(&oldPort);
  234.  
  235.     UseResFile(keepResFile = CurResFile());
  236.  
  237.     GetDialogItem(PrintingStatusDialog, 1, &itemType, (Handle *)&proceedButton, &rct);
  238.     HiliteControl(proceedButton, 255);
  239.     GetDialogItem(PrintingStatusDialog, 2, &itemType, (Handle *)&pauseButton, &rct);
  240.  
  241.     paused = false;
  242.     do {
  243.         if (GetNextEvent((mDownMask + mUpMask + updateMask), &anEvent)) {
  244.             if (PrintingStatusDialog != FrontWindow ())
  245.             SelectWindow(PrintingStatusDialog);
  246.  
  247.             if (IsDialogEvent(&anEvent)) {
  248.                 button = DialogSelect(&anEvent, &aDialog, &item);
  249.  
  250.                 if ((button) && (aDialog == PrintingStatusDialog)) {
  251.                     switch (item) {
  252.                         case 1:
  253.                             HiliteControl(pauseButton, 0);        /* Enable PAUSE    */
  254.                             HiliteControl(proceedButton, 255);    /* Disable PROCEED */
  255.                             paused = false;
  256.                             break;
  257.                         case 2:
  258.                             HiliteControl(pauseButton, 255);    /* Disable PAUSE  */
  259.                             HiliteControl(proceedButton, 0);    /* Enable PROCEED */
  260.                             paused = true;
  261.                             break;
  262.                         case 3:
  263.                             PrSetError(iPrAbort);               /* CANCEL printing */
  264.                             paused = false;
  265.                             break;
  266.                     }
  267.                 }
  268.             }
  269.         }
  270.     } while (paused != false); 
  271.  
  272.     SetPort(oldPort);
  273. }
  274.  
  275.  
  276.  
  277. /*****************************************************************************/
  278.  
  279.  
  280.  
  281. OSErr    PresentStyleDialog(FileRecHndl frHndl)
  282. {
  283.     OSErr        err;
  284.     THPrint        prRecHndl;
  285.  
  286.     if (!(prRecHndl = (THPrint)NewHandle(sizeof(TPrint))))
  287.         return(memFullErr);
  288.  
  289.     PrOpen();
  290.  
  291.     if (!(err = PrError())) {
  292.  
  293.         BlockMove((Ptr)&(*frHndl)->doc.print, (Ptr)*prRecHndl, sizeof(TPrint));
  294.             /* Get data, valid or not. */
  295.  
  296.         if (!(*frHndl)->doc.printRecValid) PrintDefault(prRecHndl);
  297.         else                                PrValidate(prRecHndl);
  298.         if (!(err = PrError())) {
  299.             if (PrStlDialog(prRecHndl)) {
  300.                 BlockMove((Ptr)*prRecHndl, (Ptr)&(*frHndl)->doc.print, sizeof(TPrint));
  301.                 (*frHndl)->doc.printRecValid  = true;
  302.                 (*frHndl)->fileState.docDirty = true;
  303.             }
  304.             else err = userCanceledErr;
  305.         }
  306.     }
  307.  
  308.     DisposeHandle((Handle)prRecHndl);
  309.     PrClose();
  310.  
  311.     return(err);
  312. }
  313.  
  314.  
  315.  
  316.